<template>

    <div class="refresh" id="refresh">

        <slot name="upTilte"></slot>

        <slot></slot>

        <slot name="downTilte"></slot>

    </div>

</template>

<script>

export default {

    name: 'PullupOrPulldownRefresh',

    props: {

        // 最大移动距离

        maxMove: {

            type: Number,

            default: 300

        },

        // 阻尼系数

        friction: {

            type: Number,

            default: 0.3

        }

    },

    data() {

        return {

            startY: 0,

            ul: null,

            draw: null,

            up: null,

            down: null,

            y: 0 // 惯性回弹的距离

        }

    },

    mounted() {

        this.$nextTick(() => {

            this.draw = document.getElementById('refresh')

            this.ul = this.draw.children[1]

            this.up = this.draw.children[0]

            this.down = this.draw.children[2]

            this.draw.addEventListener('touchstart', this.touchstart)

            this.draw.addEventListener('touchmove', this.touchmoveEvent)

            this.draw.addEventListener('touchend', this.touchendEvent)

        })

    },

    methods: {

        // 触摸开始事件

        touchstart(event) {

            this.startY = event.changedTouches[0].clientY

        },

        // 触摸移动事件

        touchmoveEvent(event) {

            const height = this.ul.clientHeight - this.draw.clientHeight

            if (height === this.draw.scrollTop || this.draw.scrollTop === 0) {

                var a = event.changedTouches[0].clientY - this.startY

                this.y = a <= this.maxMove ? a : this.maxMove

                // 为了清除卡顿问题，需要清除过渡效果

                this.ul.style.transition = 'none'

                this.ul.style.transform = 'translateY(' + this.friction * this.y + 'px)'

                // 修改状态

                const upHeight = -this.up.clientHeight + this.friction * this.y

                // 下拉开始

                if (this.friction * this.y > 0) (this.setStatus(this.friction * this.y), this.up.style.transition = 'none', this.up.style.transform = 'translateY(' + upHeight + 'px) translateX(-50%)')

                // 上拉开始

                if (this.friction * this.y < 0) (this.setStatus(this.friction * this.y), this.down.style.transition = 'none', this.down.style.marginTop = this.friction * this.y + 'px')

            }

        },

        // 触摸结束事件

        touchendEvent(event) {

            if (this.friction * this.y >= 50) this.$emit('RefreshUp', this.friction * this.y)

            else if (this.friction * this.y < -50) this.$emit('RefreshDown', this.friction * this.y)

            else this.resetStyle()

        },

        // 重置并且添加过渡效果

        resetStyle() {

            this.ul.style.transition = 'transform .6s'

            this.ul.style.transform = 'translateY(' + 0 + 'px)'

            this.up.style.transition = 'all .6s'

            this.up.style.transform = 'translateY(-' + this.up.clientHeight + 'px) translateX(-50%)'

            this.down.style.transition = 'all .6s'

            this.down.style.marginTop = -this.down.clientHeight + 'px'

        },

        // 设置刷新状态

        setStatus(y) {

            this.$emit('setStatus', y)

        }

    }

}

</script>

<style lang="scss">
.refresh {

    width: 100%;

    height: 100vh;

    border: 2px solid #ccc;

    position: relative;

    overflow: hidden;

    overflow: auto;

    position: fixed;

    ul {

        zoom: 1;

        padding: 0 10%;

    }

    ul::after {

        content: '';

        display: block;

        visibility: hidden;

        height: 0;

        clear: both;

    }

    li {

        list-style: none;

        width: 100%;

        height: 50px;

        line-height: 50px;

        text-align: center;

    }

    .UpRefresh {

        position: absolute;

        left: 50%;

        transform: translateX(-50%);

        z-index: -9;

    }

    .DownRefresh {

        position: relative;

        left: 50%;

        transform: translateX(-50%);

        margin-top: -10px;

        z-index: -9;

    }

}
</style>